package com.ggb.reactive.handler


import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.ggb.reactive.constant.TOKEN
import com.ggb.reactive.constant.USER_ID
import com.ggb.reactive.model.Result
import com.ggb.reactive.properties.JwtProperties
import com.ggb.reactive.service.JwtSigner
import lombok.AllArgsConstructor
import lombok.SneakyThrows
import lombok.extern.slf4j.Slf4j
import org.springframework.context.annotation.Bean
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.codec.ServerCodecConfigurer
import org.springframework.http.codec.json.Jackson2JsonDecoder
import org.springframework.http.codec.json.Jackson2JsonEncoder
import org.springframework.http.server.reactive.ServerHttpResponse
import org.springframework.stereotype.Component
import org.springframework.web.reactive.result.view.ViewResolver
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono
import java.io.UnsupportedEncodingException


@Component
@Slf4j
@AllArgsConstructor
class JwtWebFilter(private val jwtSigner: JwtSigner) : WebFilter {

    @Throws(JsonProcessingException::class, UnsupportedEncodingException::class)
    protected fun writeErrorMessage(response: ServerHttpResponse, status: HttpStatus, msg: String?): Mono<Void> {
        response.headers.contentType = MediaType.APPLICATION_JSON
        //val mapper = ObjectMapper()
        // 使用 Result.error() 来创建错误响应
        val errorResponse = Result<String>(status.value(),msg ?: "Internal Server Error",null )
        //val body = mapper.writeValueAsString(errorResponse)
        val dataBuffer = response.bufferFactory().wrap(ObjectMapper().writeValueAsBytes(errorResponse))
        return response.writeWith(Mono.just(dataBuffer))
    }



    @SneakyThrows
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        val request = exchange.request
        val response = exchange.response
        val path = request.path.value()
        if (
            path.contains("/user/login") ||
            path.contains("//notify") ||
            path.contains("/ws") ||
            path.contains("/admin/employee/login") ||
            path.contains("user/shop/status") ||
            path.startsWith("/v3/swagger-ui/") || // 为Swagger UI的路径
            path.startsWith("/v3/api-docs") || // 为API文档的路径
            path.startsWith("/v3/swagger-resources") || // 为Swagger的资源文件路径
            path.startsWith("/v3/webjars/") || // 为Swagger UI的webjars资源路径
            path == "/v3/swagger-ui.html"|| // 如果你的Swagger页面是这个路径
            path == "/v3/doc.html"
        ) return chain.filter(exchange)

        val token = request.headers.getFirst(TOKEN)
            ?: return writeErrorMessage(response, HttpStatus.NOT_ACCEPTABLE, "没有携带token")
        //if (token == null) {
        //    return writeErrorMessage(response, HttpStatus.NOT_ACCEPTABLE, "没有携带token")
        //}
        //else if (!auth.startsWith(jwtSigner.TOKEN_PREFIX)) {
        //    return writeErrorMessage(
        //        response,
        //        HttpStatus.NOT_ACCEPTABLE,
        //        ("token 没有以" + jwtSigner.TOKEN_PREFIX) + "开始"
        //    )
        //}
        //val token: String = auth.replace(jwtSigner.TOKEN_PREFIX, "")
        try {
            val claim = jwtSigner.parseToken(token)
            //println("用户userId ${claim[jwtSigner.authoritiesTag]}")
            exchange.attributes[USER_ID] = claim[jwtSigner.authoritiesTag]
        } catch (e: Exception) {
            return writeErrorMessage(response, HttpStatus.INTERNAL_SERVER_ERROR, e.message)
        }
        return chain.filter(exchange)

    }

}

